package com.duowei.diandan.app;

import android.os.Handler;
import android.os.Looper;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.util.Log;

import com.duowei.diandan.bean.Money;
import com.duowei.diandan.bean.Payment;
import com.duowei.diandan.bean.QrCodePay;
import com.duowei.diandan.bean.Ticket;
import com.duowei.diandan.bean.UserCardInfo;
import com.duowei.diandan.bean.food.OrderItem;
import com.duowei.diandan.bean.food.Single;
import com.duowei.diandan.constant.Settings;
import com.duowei.diandan.db.AppDatabase;
import com.duowei.diandan.db.dao.WmlsbDao;
import com.duowei.diandan.db.entry.Gklx;
import com.duowei.diandan.db.entry.Jycssz;
import com.duowei.diandan.db.entry.Jyxmsz;
import com.duowei.diandan.db.entry.Tcsd;
import com.duowei.diandan.db.entry.Wmlsb;
import com.duowei.diandan.db.entry.Wmlsbjb;

import org.joda.time.LocalDateTime;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Observable;

public class OrderList extends Observable {
    private static OrderList sOrderList;

    private Handler mHandler;
    private AppDatabase mDb;

    private Wmlsbjb mWmlsbjb;
    private List<OrderItem> mOrderItemList = new ArrayList<>();
    private Money mMoney = new Money();

    private UserCardInfo mUserCardInfo;

    private List<Payment> mPaymentList;

    private QrCodePay mQrCodePay;
    private boolean mIsCloudQrCode = false;

    /** 会员模式, 当前登录用户使用会员价几; 0代表没有会员价 */
    private int mCurrentMemberGrade = 0;

    private OrderList() {
        mDb = AppDatabase.getDatabase();
        mHandler = new Handler(Looper.getMainLooper());
    }

    public static OrderList getInstance() {
        if (sOrderList == null) {
            sOrderList = new OrderList();
        }

        return sOrderList;
    }

    /**
     * 创建Wmlsbjb
     */
    public void createWmlsbjb() {
        createWmlsbjb(null);
    }

    /**
     * 创建Wmlsbjb
     */
    public void createWmlsbjb(Jycssz jycssz) {
        createWmlsbjb(jycssz, null, 1);
    }

    public void createWmlsbjb(Jycssz jycssz, Gklx gklx, int peopleNum) {
        // 清除之前的数据
        mDb.wmlsbjbDao().deleteAll();
        mDb.wmlsbDao().deleteAll();

        // 创建
        String wmdbh = Settings.DEVICE_NAME + SqlServerDateTime.getInstance().getyyyyMMddHHmmssSSSStr();

        Wmlsbjb wmlsbjb = new Wmlsbjb();
        wmlsbjb.setWmdbh(wmdbh);
        wmlsbjb.setYhbh(Settings.DEFAULT_YHJBQK.getYhmc());
        wmlsbjb.setJysj(new LocalDateTime());
        wmlsbjb.setJsj(Settings.DEVICE_NAME);

        wmlsbjb.setBy12("2");

        if (jycssz != null) {
            wmlsbjb.setZh(jycssz.getCsmc() + ",");
        }

        if (gklx != null) {
            wmlsbjb.setJcfs(gklx.getGklx());
        }

        wmlsbjb.setJcrs((float) peopleNum);

        mDb.wmlsbjbDao().insert(wmlsbjb);
    }

    public UserCardInfo getUserCardInfo() {
        return mUserCardInfo;
    }

    public void setUserCardInfo(UserCardInfo userCardInfo) {
        mUserCardInfo = userCardInfo;
    }

    public List<Payment> getPaymentList() {
        return mPaymentList;
    }

    public void setPaymentList(List<Payment> paymentList) {
        mPaymentList = paymentList;
    }

    ;

    public QrCodePay getQrCodePay() {
        return mQrCodePay;
    }

    public void setQrCodePay(QrCodePay qrCodePay) {
        mQrCodePay = qrCodePay;
    }

    public boolean isCloudQrCode() {
        return mIsCloudQrCode;
    }

    public void setCloudQrCode(boolean cloudQrCode) {
        mIsCloudQrCode = cloudQrCode;
    }

    public int getCurrentMemberGrade() {
        return mCurrentMemberGrade;
    }

    /**
     * 重设用户没有使用会员价
     */
    public void resetCurrentMemberGrade() {
        mCurrentMemberGrade = 0;
    }

    public Wmlsbjb getWmlsbjb() {
        return mWmlsbjb;
    }

    public List<OrderItem> getOrderItemList() {
        return new ArrayList<>(mOrderItemList);
    }

    public Money getMoney() {
        return mMoney;
    }

    public void refreshData(OnRefreshCompleteListener listener) {
        new Thread(() -> {
            performRefresh();

            mHandler.post(() -> {
                if (listener != null) {
                    listener.onRefreshComplete(getOrderItemList());
                }
            });

        }).start();
    }

    /**
     * 已结账, 清空数据
     */
    @WorkerThread
    public void clearAll() {
        mDb.wmlsbjbDao().deleteAll();
        mDb.wmlsbDao().deleteAll();
    }

    /**
     * 清空购物车
     *
     * @param listener
     */
    public void clear(OnRefreshCompleteListener listener) {
        new Thread(() -> {
            mDb.wmlsbDao().deleteAll();

            performRefresh();

            if (listener != null) {
                mHandler.post(() -> listener.onRefreshComplete(getOrderItemList()));
            }

        }).start();
    }

    public void removeCartItem(OrderItem item, OnRefreshCompleteListener listener) {
        new Thread(() -> {
            Wmlsb main = item.getMain();
            if (main.getSl() <= 1) {
                mDb.wmlsbDao().delete(main);
                for (Wmlsb child : item.getChildList()) {
                    mDb.wmlsbDao().delete(child);
                }
            } else {
                // > 1
                main.setSl(main.getSl() - 1);
                mDb.wmlsbDao().update(main);
                for (Wmlsb child : item.getChildList()) {
                    child.setSl(child.getSl() - 1);
                    mDb.wmlsbDao().update(child);
                }
            }

            performRefresh();

            if (listener != null) {
                mHandler.post(() -> listener.onRefreshComplete(getOrderItemList()));
            }
        }).start();
    }

    public void addCartItem(OrderItem item, OnRefreshCompleteListener listener) {
        new Thread(() -> {
            Wmlsb main = item.getMain();
            main.setSl(main.getSl() + 1);
            mDb.wmlsbDao().update(main);

            for (Wmlsb child : item.getChildList()) {
                child.setSl(child.getSl() + 1);
                mDb.wmlsbDao().update(child);
            }

            performRefresh();

            if (listener != null) {
                mHandler.post(() -> listener.onRefreshComplete(getOrderItemList()));
            }

        }).start();
    }

    public void changeCartItem(OrderItem item, float inputNum,OnRefreshCompleteListener listener) {
        new Thread(() -> {
            Wmlsb main = item.getMain();
            main.setSl(inputNum);
            mDb.wmlsbDao().update(main);

            for (Wmlsb child : item.getChildList()) {
                child.setSl(inputNum);
                mDb.wmlsbDao().update(child);
            }

            performRefresh();

            if (listener != null) {
                mHandler.post(() -> listener.onRefreshComplete(getOrderItemList()));
            }

        }).start();
    }

    // ----------------------------

    public void addSingle(Single single, String tasteString, List<Wmlsb> childWmlsbList) {
        new Thread(() -> {
            Wmlsb wmlsb = new Wmlsb(single.getItem(), true, 0);

            wmlsb.setDj(single.getPrice());

            if (tasteString != null) {
                wmlsb.setPz(tasteString);
            }

            long mainId = mDb.wmlsbDao().insert(wmlsb);

            if (childWmlsbList != null && childWmlsbList.size() > 0) {
                for (Wmlsb childWmlsb : childWmlsbList) {
                    childWmlsb.setMainId(mainId);
                }

                mDb.wmlsbDao().insert(childWmlsbList);
            }

            performRefresh();

        }).start();
    }

    public void addMeal(Tcsd main, List<Tcsd> childList, OnRefreshCompleteListener listener) {
        new Thread(() -> {
            WmlsbDao wmlsbDao = AppDatabase.getDatabase().wmlsbDao();

            String datetime = SqlServerDateTime.getInstance().getyyyyMMddHHmmssSSSStr();
            LocalDateTime ldt = SqlServerDateTime.getInstance().getNowServerDateTime();

            Wmlsb item = new Wmlsb(main, "1", datetime, true, 0);
            item.setDj(main.getPrice());
            item.setBy5(ldt);
            long mainId = wmlsbDao.insert(item);

            if (childList != null) {
                for (Tcsd t : childList) {
                    Wmlsb item1 = new Wmlsb(t, "0", datetime, false, mainId);
                    item1.setBy5(ldt);
                    item1.setPz(t.getPz());

                    wmlsbDao.insert(item1);
                }
            }

            performRefresh();

            if (listener != null) {
                mHandler.post(() -> listener.onRefreshComplete(getOrderItemList()));
            }

        }).start();
    }

    public void addMeal(Tcsd main) {
        addMeal(main, null, null);
    }
    /**
     * 计算云会员折扣(非会员模式调用)
     */
    public void computeCloudDiscount(UserCardInfo userCardInfo) {
        new Thread(() -> {
            List<Wmlsb> wmlsbList = mDb.wmlsbDao().findAll();
            if (userCardInfo != null && !TextUtils.isEmpty(userCardInfo.getCardGrade())) {
                // cardgrade":"实体卡"
                String zkfs = mDb.fxhykszDao().queryZkfsByHykdj(userCardInfo.getCardGrade());
                for (Wmlsb w : wmlsbList) {
                    Jyxmsz jyxmsz = mDb.jyxmszDao().findByXmbh(w.getXmbh());

                    if (jyxmsz != null) {
                        boolean changed = false;

                        if (!TextUtils.isEmpty(zkfs)) {
                            switch (zkfs) {
                                case "会员价1":
                                    if (jyxmsz.getHyj() != null && jyxmsz.getHyj() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj()
                                                && w.getDj() > jyxmsz.getHyj()) {
                                            w.setDj(jyxmsz.getHyj());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价2":
                                    if (jyxmsz.getHyj2() != null && jyxmsz.getHyj2() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj2()
                                                && w.getDj() > jyxmsz.getHyj2()) {
                                            w.setDj(jyxmsz.getHyj2());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价3":
                                    if (jyxmsz.getHyj3() != null && jyxmsz.getHyj3() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj3()
                                                && w.getDj() > jyxmsz.getHyj3()) {
                                            w.setDj(jyxmsz.getHyj3());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价4":
                                    if (jyxmsz.getHyj4() != null && jyxmsz.getHyj4() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj4()
                                                && w.getDj() > jyxmsz.getHyj4()) {
                                            w.setDj(jyxmsz.getHyj4());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价5":
                                    if (jyxmsz.getHyj5() != null && jyxmsz.getHyj5() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj5()
                                                && w.getDj() > jyxmsz.getHyj5()) {
                                            w.setDj(jyxmsz.getHyj5());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价6":
                                    if (jyxmsz.getHyj6() != null && jyxmsz.getHyj6() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj6()
                                                && w.getDj() > jyxmsz.getHyj6()) {
                                            w.setDj(jyxmsz.getHyj6());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价7":
                                    if (jyxmsz.getHyj7() != null && jyxmsz.getHyj7() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj7()
                                                && w.getDj() > jyxmsz.getHyj7()) {
                                            w.setDj(jyxmsz.getHyj7());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价8":
                                    if (jyxmsz.getHyj8() != null && jyxmsz.getHyj8() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj8()
                                                && w.getDj() > jyxmsz.getHyj8()) {
                                            w.setDj(jyxmsz.getHyj8());
                                            changed = true;
                                        }
                                    }
                                    break;
                                case "会员价9":
                                    if (jyxmsz.getHyj9() != null && jyxmsz.getHyj9() > 0) {
                                        if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj9()
                                                && w.getDj() > jyxmsz.getHyj9()) {
                                            w.setDj(jyxmsz.getHyj9());
                                            changed = true;
                                        }
                                    }
                                    break;
                            }
                        } else {
                            if (jyxmsz.getHyj9() != null && jyxmsz.getHyj9() > 0) {
                                if (w.getYsjg() != null && w.getYsjg() > jyxmsz.getHyj9()
                                        && w.getDj() > jyxmsz.getHyj9()) {
                                    w.setDj(jyxmsz.getHyj9());
                                    changed = true;
                                }
                            }
                        }

                        if (changed) {
                            mDb.wmlsbDao().update(w);
                        }
                    }
                }
            }

            BigDecimal allDj = new BigDecimal("0");
            BigDecimal allYsjg = new BigDecimal("0");

            for (int i = 0; i < wmlsbList.size(); i++) {
                Wmlsb w = wmlsbList.get(i);
                allDj = allDj.add(new BigDecimal(w.getDj()).multiply(new BigDecimal(w.getSl())));
                allYsjg = allYsjg.add(new BigDecimal(w.getYsjg()).multiply(new BigDecimal(w.getSl())));
            }

            mMoney.setDiscount(allYsjg.subtract(allDj));
        }).start();
    }

    /**
     * 根据云会员付款方式明细,更新Money
     */
    public void computeCloudMoneyWithPayment(List<Payment> list) {
        BigDecimal paidMoney = new BigDecimal("0");
        for (int i = 0; i < list.size(); i++) {
            paidMoney = paidMoney.add(BigDecimal.valueOf(list.get(i).payMoney));
        }
        mMoney.setPaid(paidMoney);
    }

    // ---
    // ---
    // ---

    /**
     * 下单模式使用
     */
    @WorkerThread
    public synchronized void handleWmlsb() {
        // 套餐主项、子项同步显示处理
        List<Wmlsb> wmlsbList = mDb.wmlsbDao().findByBy6EqualOne();
        for (Wmlsb w : wmlsbList) {
            w.setMain(true);
            mDb.wmlsbDao().update(w);

            List<Wmlsb> childList = mDb.wmlsbDao().findChildByTcbh(w.getTcbh());
            for (Wmlsb cw : childList) {
                cw.setMainId(w.getId());
                cw.setMain(false);
            }
            mDb.wmlsbDao().update(childList);
        }
    }

    @WorkerThread
    public synchronized void performRefresh() {
        mWmlsbjb = mDb.wmlsbjbDao().findOne();

        mOrderItemList.clear();
        List<Wmlsb> mainList = mDb.wmlsbDao().findMainList();
        for (Wmlsb w : mainList) {
            List<Wmlsb> childList = mDb.wmlsbDao().findChildList(w.getId());
            OrderItem ci = new OrderItem(w, childList);
            mOrderItemList.add(ci);
        }

        // ----
        List<Wmlsb> allList = mDb.wmlsbDao().findAll();
        BigDecimal total = new BigDecimal("0");
        BigDecimal actual = new BigDecimal("0");
        for (Wmlsb w : allList) {
            total = total.add(new BigDecimal(w.getSl()).multiply(new BigDecimal(w.getYsjg())));
            actual = actual.add(new BigDecimal(w.getSl()).multiply(new BigDecimal(w.getDj())));
        }
        BigDecimal discount = total.subtract(actual).setScale(2, BigDecimal.ROUND_HALF_UP);

        mMoney.setTotal(total);
        mMoney.setDiscount(discount);

        mWmlsbjb.setYsje(mMoney.getTotalFloat());
        mWmlsbjb.setYs(mMoney.getReceivableFloat());
        mWmlsbjb.setSs(mMoney.getReceivableFloat());
        mWmlsbjb.setZk(mMoney.getDiscountFloat());
        mDb.wmlsbjbDao().update(mWmlsbjb);

        // --
        mHandler.post(() -> {
            setChanged();
            notifyObservers();
        });
    }

    /**
     * 计算使用会员价几(会员模式)
     */
    public void computeCurrentMemberGrade() {
        mCurrentMemberGrade = 0; // 设为0

        if (mUserCardInfo != null && !TextUtils.isEmpty(mUserCardInfo.getCardGrade())) {
            // cardgrade":"实体卡"
            String zkfs = mDb.fxhykszDao().queryZkfsByHykdj(mUserCardInfo.getCardGrade());

            if (!TextUtils.isEmpty(zkfs)) {
                switch (zkfs) {
                    case "会员价1":
                        mCurrentMemberGrade = 1;
                        break;
                    case "会员价2":
                        mCurrentMemberGrade = 2;
                        break;
                    case "会员价3":
                        mCurrentMemberGrade = 3;
                        break;
                    case "会员价4":
                        mCurrentMemberGrade = 4;
                        break;
                    case "会员价5":
                        mCurrentMemberGrade = 5;
                        break;
                    case "会员价6":
                        mCurrentMemberGrade = 6;
                        break;
                    case "会员价7":
                        mCurrentMemberGrade = 7;
                        break;
                    case "会员价8":
                        mCurrentMemberGrade = 8;
                        break;
                    case "会员价9":
                        mCurrentMemberGrade = 9;
                        break;
                }
            } else {
                // 未发现匹配会员价时,使用会员价9
                mCurrentMemberGrade = 9;
            }
        }
    }

    /**
     * 恢复原价
     *
     * @param onCompleteListener
     */
    public void recoverOriginPrice(OnCompleteListener onCompleteListener) {
        new Thread() {
            @Override
            public void run() {
                List<Wmlsb> wmlsbList = mDb.wmlsbDao().findAll();
                for (Wmlsb w : wmlsbList) {
                    w.setDj(w.getYsjg());
                }
                mDb.wmlsbDao().update(wmlsbList);

                performRefresh();

                mHandler.post(() -> {
                    if (onCompleteListener != null) {
                        onCompleteListener.onComplete();
                    }
                });
            }
        }.start();
    }

    /**
     * 计算类型折扣
     *
     * @param ticket   类别折扣
     * @param listener 计算完成监听
     */
    public void computeCateDiscount(Ticket ticket, OnDiscountListener listener) {
        new Thread() {
            @Override
            public void run() {
                List<Wmlsb> computeWmlsbList = new ArrayList<>(); // 需要的wmlsb列表

                // 过滤数据
                List<Wmlsb> wmlsbList = mDb.wmlsbDao().findAll();
                for (Wmlsb w : wmlsbList) {
                    String cate = ticket.category;
                    if (!TextUtils.isEmpty(cate)) {
                        List<String> cateList = Arrays.asList(cate.split(","));

                        if (cateList.contains("全部类别")) {
                            computeWmlsbList.add(w);
                        } else {
                            Jyxmsz jyxmsz = mDb.jyxmszDao().findByXmbh(w.getXmbh());
                            if (jyxmsz != null && cateList.contains(jyxmsz.getLbmc())) {
                                computeWmlsbList.add(w);
                            }
                        }
                    }
                }

                // 计算折扣
                BigDecimal discount = BigDecimal.valueOf(0);
                if (ticket.discount != null) {
                    for (Wmlsb w : computeWmlsbList) {
                        discount = discount.add(new BigDecimal(w.getDj().toString())
                                .multiply(BigDecimal.valueOf(100).subtract(new BigDecimal(ticket.discount.toString()))).divide(BigDecimal.valueOf(100), BigDecimal.ROUND_HALF_UP));
                    }
                }

                BigDecimal finalDiscount = discount;
                mHandler.post(() -> {
                    if (listener != null) {
                        listener.onDiscount(finalDiscount.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
                    }
                });
            }
        }.start();
    }

    /**
     * 计算单品折扣
     *
     * @param ticket   单品折扣
     * @param listener 计算完成监听
     */
    public void computeSingleDiscount(Ticket ticket, OnDiscountListener listener) {
        new Thread() {
            @Override
            public void run() {
                List<Wmlsb> computeWmlsbList = new ArrayList<>(); // 需要的wmlsb列表

                // 过滤数据
                List<Wmlsb> wmlsbList = mDb.wmlsbDao().findAll();
                for (Wmlsb w : wmlsbList) {
                    String goodsName = ticket.goodsName;
                    if (!TextUtils.isEmpty(goodsName)) {
                        List<String> cateList = Arrays.asList(goodsName.split(","));

                        Jyxmsz jyxmsz = mDb.jyxmszDao().findByXmbh(w.getXmbh());
                        if (jyxmsz != null && cateList.contains(jyxmsz.getXmmc())) {
                            computeWmlsbList.add(w);
                        }
                    }
                }

                // 计算折扣
                BigDecimal discount = BigDecimal.valueOf(0);
                if (ticket.discount != null) {
                    for (Wmlsb w : computeWmlsbList) {
                        discount = discount.add(new BigDecimal(w.getDj().toString())
                                .multiply(BigDecimal.valueOf(100).subtract(new BigDecimal(ticket.discount.toString()))).divide(BigDecimal.valueOf(100), BigDecimal.ROUND_HALF_UP));
                    }
                }

                BigDecimal finalDiscount = discount;
                mHandler.post(() -> {
                    if (listener != null) {
                        listener.onDiscount(finalDiscount.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
                    }
                });
            }
        }.start();
    }

    /**
     * 计算单品优惠
     *
     * @param ticket   单品优惠
     * @param listener 计算完成监听
     */
    public void computeSingleDiscount2(Ticket ticket, OnDiscountListener listener) {
        new Thread() {
            @Override
            public void run() {
                List<Wmlsb> computeWmlsbList = new ArrayList<>(); // 需要的wmlsb列表

                // 过滤数据
                List<Wmlsb> wmlsbList = mDb.wmlsbDao().findAll();
                for (Wmlsb w : wmlsbList) {
                    String goodsName = ticket.goodsName;
                    if (!TextUtils.isEmpty(goodsName)) {
                        List<String> cateList = Arrays.asList(goodsName.split(","));

                        Jyxmsz jyxmsz = mDb.jyxmszDao().findByXmbh(w.getXmbh());
                        if (jyxmsz != null && cateList.contains(jyxmsz.getXmmc())) {
                            computeWmlsbList.add(w);
                        }
                    }
                }

                // 计算折扣
                BigDecimal discount = BigDecimal.valueOf(0);
                for (Wmlsb w : computeWmlsbList) {
                    discount = discount.add(new BigDecimal(w.getDj().toString()));
                }

                BigDecimal finalDiscount = discount;
                mHandler.post(() -> {
                    if (listener != null) {
                        listener.onDiscount(Math.min(finalDiscount.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue(), ticket.money));
                    }
                });
            }
        }.start();
    }

    public interface OnRefreshCompleteListener {
        void onRefreshComplete(List<OrderItem> list);
    }

    public interface OnCompleteListener {
        void onComplete();
    }

    public interface OnDiscountListener {
        void onDiscount(float discount);
    }
}
